#ifndef COMMON_TRANSFORM_H
#define COMMON_TRANSFORM_H

#include "Common/Algebra/Misc.h"
#include "Common/Algebra/Vec2.h"
#include "Common/Algebra/Matr4.h"

namespace cmn {

	class Transform {
	public:
		Vec2 Vec;
		float Rot;
		float Scale;

		Transform( const Vec2& vec, float rot, float scale = 1.0f ) :
			Vec( vec ), Rot( rot ), Scale( scale ) {}

		Transform operator += ( const Transform& tf );
		Transform operator -= ( const Transform& tf );
		Transform operator *= ( const Transform& tf );
		Transform operator *= ( const float a );

		Matr4 GetMatrix() const;
		Matr4 GetInvMatrix() const;

		static const Transform Zero() { return Transform( Vec2::Zero(), 0.0f, 1.0f ); }
	};

	inline Transform operator + ( const Transform& a, const Transform& b ) {
		return Transform( a.Vec + b.Vec, a.Rot + b.Rot, a.Scale * b.Scale );
	}

	inline Transform operator - ( const Transform& a, const Transform& b ) {
		return Transform( a.Vec - b.Vec, a.Rot - b.Rot, a.Scale / b.Scale );
	}

	inline Vec2 operator * ( const Transform& tf, const Vec2& vec ) {
		float cosA = cos( tf.Rot );
		float sinA = sin( tf.Rot );
		float x = vec.X;
		float y = vec.Y;

		return Vec2(
				   tf.Scale * cosA * x - tf.Scale * sinA * y + tf.Vec.X,
				   tf.Scale * sinA * x + tf.Scale * cosA * y + tf.Vec.Y );
	}

	inline Transform operator * ( const Transform& a, const Transform& b ) {
		return Transform( a * b.Vec, a.Rot + b.Rot );
	}

	inline Transform operator * ( const Transform& tf, const float a ) {
		return Transform( tf.Vec * a, tf.Rot * a );
	}

	inline bool operator == ( const Transform& a, const Transform& b ) {
		if( a.Vec != b.Vec ) return false;
		if( a.Rot != b.Rot ) return false;
		if( a.Scale != b.Scale ) return false;
		return true;
	}

	inline bool operator != ( const Transform& a, const Transform& b ) {
		return !( a == b );
	}
}
#endif
